package com.gitee.cnlongs.cnlongmq.server.threads;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.gitee.cnlongdb.basic.utils.RandomUtil;
import com.gitee.cnlongs.cnlongmq.basic.constant.CnLongMqConstant;
import com.gitee.cnlongs.cnlongmq.basic.entitiy.request.CnLongMessageQueue;
import com.gitee.cnlongs.cnlongmq.basic.entitiy.request.CnLongMqConfiger;
import com.gitee.cnlongs.cnlongmq.server.LongMqServer;
import com.gitee.cnlongs.cnlongmq.server.threads.datasync.CnLongMqExchangeThread;

/**
 * 系统名称：LongMqDataSync.java
 * 模块名称：
 * 模块描述：数据同步工具类
 * 功能列表：
 * 模块作者：ZOUYONG
 * 开发时间：2019年4月2日 下午8:38:14
 * 模块路径：com.gitee.cnlongs.cnlongmq.server.datasync.LongMqDataSync
 * 更新记录：
 */
public class LongMqDataSyncHandler {

	private static final Logger logger = (Logger) LoggerFactory.getLogger(LongMqDataSyncHandler.class);
	
	/**
	 * 功能描述：处理需要同步队列的数据
	 × 模块作者：ZOUYONG
	 × 开发时间：2019年4月12日 上午9:57:23
	 × 返回数据：void
	 */
	public static void handlerNeedSequeueShare(CnLongMqConfiger currLongMqConfig, String filterCustomer) {
		// 获取当前同步队列的线程编码
		String syncThreadCode = currLongMqConfig.getSyncThreadCode();
		// 如果线程编码已存在，则说明已执行过，不需要再次同步所有的队列信息至客户端
		boolean isSend = null != currLongMqConfig.getAlreadyOpertorCustomerMap().get(syncThreadCode);
		if(StringUtils.isBlank(syncThreadCode) || isSend) {
			syncThreadCode = RandomUtil.getCharAndNumr(32); // 如果为空，则自动生成一个编码
			currLongMqConfig.getAlreadyOpertorCustomerMap().put(syncThreadCode, new Date().getTime());
		}
		currLongMqConfig.setSyncThreadCode(syncThreadCode);
		
		// 获取需要同步的客户列表
		List<String> customerList = currLongMqConfig.getCustomerList();
		if(CollectionUtils.isEmpty(customerList)) {
			// 转换要同步交换的客户端信息
			String customer = currLongMqConfig.getCustomer();
			if(StringUtils.isNotBlank(customer)) {
				customerList.addAll(Arrays.asList(customer.split(CnLongMqConstant.longmqSeparateE)));
			}
			currLongMqConfig.setCustomerList(customerList);
		}
		
		// 开始发送队列交换信息
		if(!isSend) {
			new CnLongMqExchangeThread(currLongMqConfig, filterCustomer).start();
		}
	}
	
	/**
	 * 功能描述：接收同步过来的队列数据
	 * 模块作者：ZOUYONG
	 * 开发时间：2019年4月2日 下午10:13:50
	 * 更新记录：
	 * 返回数据：void
	 */
	public static String startExchangeSeqList(CnLongMqConfiger syncLongMqConfig) {
		
		return replayExchangeSeqList(syncLongMqConfig, true);
	}

	/**
	 * 功能描述：具体执行队列信息交换
	 × 模块作者：ZOUYONG
	 × 开发时间：2019年7月23日 下午7:06:53
	 × 返回数据：void
	 */
	public static String replayExchangeSeqList(CnLongMqConfiger syncLongMqConfig, boolean isSend) {
		CnLongMqConfiger currLongMqConfig = LongMqServer.getExecuter().getLongMqConfig();
		try {
			List<CnLongMessageQueue> syncSeqList = syncLongMqConfig.getCustomerSequeueList();
			List<CnLongMessageQueue> currSeqList = currLongMqConfig.getCustomerSequeueList();
			List<CnLongMessageQueue> newSeqList = new ArrayList<CnLongMessageQueue>();
			for (CnLongMessageQueue syncSeq : syncSeqList) {
				boolean isSame = false;
				for (CnLongMessageQueue currSeq : currSeqList) {
					if(currSeq.compareIdentical(syncSeq)) {
						isSame = true;
						break;
					}
				}
				if(!isSame) {
					newSeqList.add(syncSeq);
				}
			}
			if(CollectionUtils.isNotEmpty(newSeqList)) {
				// 合并交换队列
				currSeqList.addAll(newSeqList);
			}
			if(isSend) {
				StringBuffer filterCustomer = new StringBuffer(syncLongMqConfig
						.getLongMqIp()+CnLongMqConstant.longmqSeparateF+syncLongMqConfig.getLongMqPort());
				// 将同步后的队列继续同步给相关客户端
				handlerNeedSequeueShare(currLongMqConfig, filterCustomer.toString());
			}
		}
		catch(Exception e) {
			logger.error("执行同步队列操作异常：" + e.getMessage());
		}
		return JSON.toJSONString(currLongMqConfig);
	}

}
